//#########################################################################
//                              WackiEngie
//           Copyright (c) 2014 Marc Wacker. All rights reserved.
//#########################################################################

#include "WeShader.h"
#include "WeDebug.h"

namespace WackiEngine
{

	//-----------------------------------------------------------------------------
	// Error Strings
	char* aGLWEErrorString[] = { (char*)"(e0000) GLWE not enabled",
		(char*)"(e0001) not a valid program object",
		(char*)"(e0002) not a valid object",
		(char*)"(e0003) out of memory",
		(char*)"(e0004) unknown compiler error" };

	//----------------------------------------------------------------------------- 
	//! Ctor with shader filename & shader type
	Shader::Shader(const String& filename, ShaderType shaderType)
	{
		_shaderType = shaderType;
		_shaderSource = "";
		_shaderObjectGL = 0;
		_shaderFile = filename;

		// Only load file at this moment, don't compile.
		load(filename);
	}

	//----------------------------------------------------------------------------- 
	Shader::~Shader()
	{
		//WE_LOG("~WEGLShader(%s)\n", name().c_str());
		if(_shaderObjectGL)
			glDeleteShader(_shaderObjectGL);
	}
	//----------------------------------------------------------------------------- 
	//! WEGLShader::createAndCompile creates & compiles the OpenGL shader object
	bool Shader::createAndCompile()
	{
		// delete if object already exits
		if(_shaderObjectGL) glDeleteShader(_shaderObjectGL);

		if(_shaderSource != "")
		{
			switch(_shaderType)
			{
			case VertexShader:
				_shaderObjectGL = glCreateShader(GL_VERTEX_SHADER); break;
			case FragmentShader:
				_shaderObjectGL = glCreateShader(GL_FRAGMENT_SHADER); break;
			}

			String srcVersion = "";
			String scrDefines = "";

			String scrComplete = srcVersion + scrDefines + _shaderSource;

			const char* src = scrComplete.c_str();
			glShaderSource(_shaderObjectGL, 1, &src, 0);
			glCompileShader(_shaderObjectGL);

			// Check comiler log
			int compileSuccess = 0;
			glGetShaderiv(_shaderObjectGL, GL_COMPILE_STATUS, &compileSuccess);
			if(compileSuccess == GL_FALSE)
			{
				GLchar log[256];
				glGetShaderInfoLog(_shaderObjectGL, sizeof(log), 0, &log[0]);

				LOGERR("GLSL Compiler ERROR");
				LOGERR(" In File " + _shaderFile);
				LOGERR(log);

				return false;
			}
			return true;
		}
		return false;
	}
	//-----------------------------------------------------------------------------
	//! WEGLShader::load loads a shader file into string _shaderSource
	void Shader::load(const String& filename)
	{
		std::fstream shaderFile(filename.c_str(), std::ios::in);

		if(!shaderFile.is_open())
			exit(1);

		std::stringstream buffer;
		buffer << shaderFile.rdbuf();

		// remove comments because some stupid ARM compiler can't handle GLWE comments
		_shaderSource = buffer.str();
	}
	//-----------------------------------------------------------------------------
	//! WEGLShader::load loads a shader file from memory into memory 
	void Shader::loadFromMemory(const String& shaderSource)
	{
		_shaderSource = shaderSource;
	}
	// ----------------------------------------------------------------------------

}